/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package algoritmosgenetico;

/**
 *
 * @author Administrador
 */
public class Poblacion {

    private int np, nc;
    private int[][] individuos;
    private double[] fitnessValues;
    private double[] probabilidad;
    private double[] probabilidadAcumulada;
    private double fitnessMedio, minimo;
    private int[] mejorIndividuo;

    public Poblacion(int np, int nc) {
        this.np = np;
        this.nc = nc;
        individuos = new int[np][nc];
        for (int i = 0; i < individuos.length; i++) {
            for (int j = 0; j < individuos[i].length; j++) {
                individuos[i][j] = (Math.random() < 0.5) ? 0 : 1;
            }
        }
    }
    
    public Poblacion(int[][] inds) {
        this.np=inds.length;
        this.nc=inds[0].length;
        individuos=new int[np][nc];
        for (int i = 0; i < inds.length; i++) {
            System.arraycopy(inds[i], 0, individuos[i], 0, inds[i].length);
        }
    }
   
    public void calculosPoblacion(String nombre) {
        ProblemReader pr = new ProblemReader(nombre);
        fitnessMedio = 0.0;
        fitnessValues = new double[this.np];
        double sumaInverso = 0.0;
        for (int i = 0; i < individuos.length; i++) {            
            double fitness = (new CalcularSolucion(individuos[i], pr.getFixedCosts(), pr.getCosts())).getCosto();
            fitnessValues[i] = fitness;
            fitnessMedio += fitness / (this.np * 1d);
            sumaInverso += 1.0 / fitness;
        }
        minimo = fitnessValues[0];
        mejorIndividuo = new int[this.nc];
        for (int i = 1; i < fitnessValues.length; i++) {
            if (fitnessValues[i] < minimo) {
                minimo = fitnessValues[i];
                System.arraycopy(individuos[i], 0, mejorIndividuo, 0, individuos[i].length);
            }
        }
        double sumaP = 0.0;
        probabilidad = new double[this.np];
        probabilidadAcumulada = new double[this.np];
        for (int i = 0; i < fitnessValues.length; i++) {
            double probabilidadSeleccion = (1.0 / fitnessValues[i]) / sumaInverso;
            probabilidad[i] = probabilidadSeleccion;
            sumaP += probabilidadSeleccion;
            probabilidadAcumulada[i] = sumaP;
        }
    }
    
    public void imprimir(){
        for (int i = 0; i < individuos.length; i++) {
            for (int j = 0; j < individuos[i].length; j++) {
                System.out.print(individuos[i][j]+" ");
            }
            System.out.println(fitnessValues[i]);
        }
        System.out.println(fitnessMedio);
    }

    /**
     * @return the np
     */
    public int getNp() {
        return np;
    }

    /**
     * @return the nc
     */
    public int getNc() {
        return nc;
    }

    /**
     * @return the individuos
     */
    public int[][] getIndividuos() {
        return individuos;
    }

    /**
     * @return the fitnessValues
     */
    public double[] getFitnessValues() {
        return fitnessValues;
    }

    /**
     * @return the probabilidad
     */
    public double[] getProbabilidad() {
        return probabilidad;
    }

    /**
     * @return the probabilidadAcumulada
     */
    public double[] getProbabilidadAcumulada() {
        return probabilidadAcumulada;
    }

    /**
     * @return the fitnessMedio
     */
    public double getFitnessMedio() {
        return fitnessMedio;
    }

    /**
     * @return the minimo
     */
    public double getMinimo() {
        return minimo;
    }

    /**
     * @return the mejorIndividuo
     */
    public int[] getMejorIndividuo() {
        return mejorIndividuo;
    }
}
